package com.ruoyi.web.common;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.ruoyi.alert.service.IIotAlertLogService;
import com.ruoyi.alert.service.impl.IotAlertLogServiceImpl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.iot.domain.*;
import com.ruoyi.iot.enums.SensorTypeEnum;
import com.ruoyi.iot.service.IIOTSensorMsgService;
import com.ruoyi.iot.service.IIotSensorCollectService;
import com.ruoyi.iot.service.IotSensorService;
import com.ruoyi.web.common.util.*;
import com.ruoyi.web.common.util.format.TermiteUtil;
import org.apache.commons.codec.DecoderException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 定时更新数据
 */

@RestController
@RequestMapping("/iot/regularUpdate")
public class RegularUpdateController {

    @Resource
    private IIOTSensorMsgService sensorMsgService;

    @Resource
    private MsgParsingUtil parsingUtil;

    @Resource
    private IIotSensorCollectService iotService;

    @Resource
    private IotSensorService iotSensorService;

    @Resource
    private IIotAlertLogService alertLogService;
    /**
     * 调用第三方接口获取水质数据

     * @return
     */
    @PostMapping("/updateWaterQuality")
    public R updateWaterQuality() {
//        IotDataWaterQuality result = WaterQualityHTTPUtil.convertUnits();
//        if (result == null) {
//            return R.fail("获取水质数据失败");
//        }
        List<IotDataWaterQuality> iotDataWaterQualityResults = WaterQualityHTTPUtil.convertUnits();
//        IotDataWaterQuality result;
//        try {
//            result = RetryUtil.executeWithRetry(() -> {
//                return ;
////                return WaterQualityHTTPUtil.test();
//            }, 3, 10 * 1000);
//        } catch (Exception e) {
//            // 重试3次后仍然失败，标记设备为离线
////            String deviceId = iotService.queryRemoteIdBYSensorId("PH-A001");
//            iotSensorService.updateSensorOfflineStatusBySensorType(SensorTypeEnum.WATER_QUALITY);
//            return R.fail("获取水质数据失败，设备可能已离线");
//        }
//        iotSensorService.updateSensorOnlineStatusBySensorType(SensorTypeEnum.WATER_QUALITY);

        //存入mysql
        List<Map<String, Object>> collect = iotDataWaterQualityResults.stream().map(WaterQualityHTTPUtil::convertParams).collect(Collectors.toList());
        Boolean saveToMysql = iotService.batchSaveToMysql("iot_data_water_quality", collect);
        //存入influxDB
        List<Map<String, Object>> collect1 = iotDataWaterQualityResults.stream().map(WaterQualityHTTPUtil::convertInfluxdbParams).collect(Collectors.toList());
        Boolean saveToInfluxDB = iotService.batchSaveToInfluxDB("water_quality_data", collect1);



        return R.ok(iotDataWaterQualityResults);
    }

    /**
     * 调用第三方接口获取白蚁数据

     * @return
     */
    @PostMapping("/updateTermite")
    public R<IotDataWaterQuality> updateTermite() {
        List<IotDataTermite> termiteList = TermiteUtil.convertUnits();
        termiteList.forEach( termite ->{
            if(ObjectUtil.isEmpty( termite)) {
                iotSensorService.updateDeviceOfflineStatus(termite.getSensorId());
            } else {
                iotSensorService.updateDeviceOnlineStatus(termite.getSensorId());
            }
        });
        //存入mysql
        List<Map<String, Object>> collect = termiteList.stream().map(TermiteUtil::convertParams).collect(Collectors.toList());
        Boolean saveToMysql = iotService.batchSaveToMysql("iot_data_termite", collect);
        //存入influxDB
        List<Map<String, Object>> collect1 = termiteList.stream().map(TermiteUtil::convertInfluxdbParams).collect(Collectors.toList());
        Boolean saveToInfluxDB = iotService.batchSaveToInfluxDB("termite_data", collect1);
        return R.ok();
    }

    /**
     * 更新报文
     * @return
     */
    @PostMapping("/updateSensorMsg")
    public R<IotSensorMsg> updateSensorMsg() {
        List<IotSensorMsg> list = IOTSensorMsgUtil.convertUnits();
        if (list == null || list.isEmpty()) {
            return R.fail("没有数据可插入");
        }

        // 按照 remoteId + reportTime 分组，用于后续去重判断
        List<IotSensorMsg> filteredList = list.stream()
                .filter(msg -> {
                    // 查询是否已存在相同 remoteId + reportTime 的记录
                    return !sensorMsgService.existsByRemoteIdAndReportTime(
                            msg.getRemoteId(),
                            msg.getReportTime()
                    );
                })
                .collect(Collectors.toList());

        if (!filteredList.isEmpty()) {
            // 批量插入去重后的数据
            sensorMsgService.batchInsert(filteredList);
        }

        List<IotSensorMsg> msgList = sensorMsgService.selectSensorMsgByType("遥测终端");
        msgList.forEach(item->{
            try {
                parsingUtil.parseMsg(item.getMsg());
            } catch (DecoderException e) {
                throw new RuntimeException(e);
            }
        });
        return R.ok();
    }

    /**
     * 更新遥测终端数据
     * @return
     */
    @PostMapping("/updateMsgToData")
    public R<IotSensorMsg> updateMsgToData() {
        List<IotSensorMsg> msgList = sensorMsgService.selectSensorMsgByType("遥测终端");
        msgList.forEach(item->{
            try {
                parsingUtil.parseMsg(item.getMsg());
            } catch (DecoderException e) {
                throw new RuntimeException(e);
            }
        });
        sensorMsgService.batchUpdateState(msgList);
        return R.ok();
    }

    @PostMapping("/updateMsgToSYData")
    public R<IotSensorMsg> updateMsgToSYData() {
        List<IotSensorMsg> msgList = sensorMsgService.selectSensorMsgByType("MCU终端");
        msgList.forEach(item->{
            try {
                parsingUtil.parseSYMsg(item.getMsg());
            } catch (DecoderException e) {
                throw new RuntimeException(e);
            }
        });
        sensorMsgService.batchUpdateState(msgList);
        return R.ok();
    }

    @PostMapping("/updateGnss")
    public R updateGNSSData() {
        List<IotDataGnss> list = IOTGnssMsgUtil.convertUnits();
        if (list == null) {
            scheduleRetryGNSS();
            return R.fail("获取gnss数据失败,重新获取");
        }
        // 正常处理逻辑
        processGNSSData(list);
        return R.ok(list);
    }

    @Async
    public void scheduleRetryGNSS() {
        try {
            // 等待20分钟
            Thread.sleep(20 * 60 * 1000);
            // 重新执行GNSS数据更新
            retryGNSSData();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    @PostMapping("/test")
    public R<IotSensorMsg> test() {
//        List<IotSensorMsg> msgList = sensorMsgService.selectSensorMsgByType("遥测终端");
//        msgList.forEach(item->{
        String item = "7E7E0242082121571234340074020330250726090000F1F142082121574BF0F02507260805F4600000000000000000000000002619002278F5C01FB41FB41FB41FB41FB41FB41FB41FB41FB41FB41FB41FB42019000000391A00811621190000002219000000231900000024190000001A19000000F81A000251F71001373812122803E739";
            try {
                parsingUtil.parseMsg(item);
            } catch (DecoderException e) {
                throw new RuntimeException(e);
            }
//        });
//        sensorMsgService.batchUpdateState(msgList);
        return R.ok();
    }

    /**
     * 调用第三方接口获取气象数据

     * @return
     */
    @PostMapping("/updateWeather")
    public R<IotDataWeather> updateWeather() throws InvalidKeySpecException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
        IotDataWeather result = WeatherUtil.convertUnits();
        System.out.println(result);
        if (result == null) {
            return R.fail("获取气象数据失败");
        }
        Map<String, String> tags = new HashMap<>();
        Map<String, Object> fields = new HashMap<>();
        //获取水质设备的遥测终端编号 默认取PH值编号
        String remoteId = "weathertest";
        tags.put("remote_id", remoteId);
        tags.put("device_id", remoteId);

        fields.put("temp", result.getTemp());
        fields.put("feels_like", result.getFeelsLike());
        fields.put("humidity", result.getHumidity());
        fields.put("precip", result.getPrecip());
        fields.put("pressure",result.getPressure());
        fields.put("wind_scale", result.getWindScale());
        fields.put("wind_dir", result.getWindDir());
        fields.put("vis", result.getVis());
        fields.put("dew", result.getDew());
        fields.put("cloud", result.getCloud());
        fields.put("report_time", result.getReportTime());

        fields.put("fx_time_forecast", result.getFxTimeForecast());
        fields.put("temp_forecast", result.getTempForecast());
        fields.put("wind_dir_forecast", result.getWindDirForecast());
        fields.put("wind_scale_forecast", result.getWindScaleForecast());
        fields.put("wind_speed_forecast",result.getWindSpeedForecast());
        fields.put("humidity_forecast", result.getHumidityForecast());
        fields.put("pop_forecast", result.getPopForecast());
        fields.put("precip_forecast", result.getPrecipForecast());
        fields.put("pressure_forecast", result.getPressureForecast());
        fields.put("cloud_forecast", result.getCloudForecast());
        fields.put("dew_forecast", result.getDewForecast());
        fields.put("fx_time_minutely", result.getFxTimeMinutely());
        fields.put("precip_minutely", result.getPrecipMinutely());
        fields.put("type_minutely", result.getTypeMinutely());
        //更新mysql数据库  多条记录更新
        boolean saveToMysql = iotService.saveToMysql("iot_data_weather",tags,fields);
        //新增influxDB 数据

        // 后续再去掉 reportTime 字段（不影响前面的操作）
        Map<String, Object> filteredFields = new HashMap<>(fields);
        //移除原先的数据，并添加时间戳格式的时间
        filteredFields.remove("report_time");
        filteredFields.put("reportTime", result.getReportTime().getTime());
        Map<String, String> influxdbTags = new HashMap<>();
        influxdbTags.put("remoteId", remoteId);
        influxdbTags.put("deviceId", remoteId);
        boolean saveToInfluxDB = iotService.saveToInfluxDB("weather_data",influxdbTags,filteredFields);


        return R.ok(result);
    }

    @PostMapping("/testt")
    public R<Void> testt() {
        String data =
                "7e7e010011111112000032002b02002b200321153057f1f1001111111248f0f020032115303922000098362019000000261900000038122400037b54";
        Map<String,String> tags = new HashMap<>();

        Map<String,Object> stringObjectMap = new HashMap<>();
//        stringObjectMap.put("gpsTotalX", 15);
        stringObjectMap.put("valuePH", 12);

        tags.put("device_id", "PH-A001");
        tags.put("remote_id", "b070209243");
//        tags.put("remote_id", "b070209350");
        alertLogService.hanlerAlert("iot_data_water_quality", tags, stringObjectMap );
//        iIotAlertLogService.hanlerAlert("iot_data_gnss", tags, stringObjectMap );


//        Map<String, String> tags = new HashMap<>();
//        Map<String, Object> fields = new HashMap<>();
//        //获取水质设备的遥测终端编号 默认取PH值编号
//        String remoteId = iotService.queryRemoteIdBYSensorId("PH-A001");
//        tags.put("remote_id", remoteId);
//        fields.put("test","123");
//
//        //更新mysql数据库  多条记录更新
//        boolean saveToMysql = iotService.saveToMysql("iot_data_water_quality",tags,fields);



        return R.ok();
    }


    private void retryGNSSData() {
        List<IotDataGnss> list = IOTGnssMsgUtil.convertUnits();
        if (list != null) {
            processGNSSData(list);
        }
    }

    private R processGNSSData(List<IotDataGnss> list) {
        //存入mysql
        List<Map<String, Object>> collect = list.stream().map(IOTGnssMsgUtil::convertParams).collect(Collectors.toList());
        Boolean saveToMysql = iotService.batchSaveToMysql("iot_data_gnss", collect);
        //存入influxDB
        List<Map<String, Object>> collect1 = list.stream().map(IOTGnssMsgUtil::convertInfluxdbParams).collect(Collectors.toList());
        Boolean saveToInfluxDB = iotService.batchSaveToInfluxDB("gnss_data", collect1);
        return R.ok(list);
    }
    /**
     * 第三方调用该接口传输水质数据

     * @return
     */
    @PostMapping("/sendWaterQualityData")
    public R sendWaterQualityData(@RequestBody JSONObject jsonObject) {
        if(ObjectUtil.isEmpty(jsonObject)){
            return R.fail("参数错误");
        }
//        List<IotDataWaterQuality> iotDataWaterQualityResults = WaterQualityHTTPUtil.convertUnits();
        List<IotDataWaterQuality> iotDataWaterQualityResults = WaterQualityHTTPUtil.jsonToList(jsonObject);
        //存入mysql
        List<Map<String, Object>> collect = iotDataWaterQualityResults.stream().map(WaterQualityHTTPUtil::convertParams).collect(Collectors.toList());
        Boolean saveToMysql = iotService.batchSaveToMysql("iot_data_water_quality", collect);
        //存入influxDB
        List<Map<String, Object>> collect1 = iotDataWaterQualityResults.stream().map(WaterQualityHTTPUtil::convertInfluxdbParams).collect(Collectors.toList());
        Boolean saveToInfluxDB = iotService.batchSaveToInfluxDB("water_quality_data", collect1);



        return R.ok(iotDataWaterQualityResults);
    }
    //
}
